#include "stdafx.h"
#include "Support.h"
#include "../Parser/Vals.h"
#include "Lexecutioner.h"
#include "Environment.h"
#include <sstream>
#include <iomanip>
#include <memory>
#include "MiniBasic_h.h"

namespace MiniBasic
{
    //std::string StringifyExpression(const var_type& v1, mbint numberPadding)
    //{
    //    std::string retStr;
    //    if(!GetExprValue(v1, retStr)) // if it's not a string
    //    {
    //        mbint num;
    //        std::ostringstream str;
    //        Variable* var;
    //        if(!GetExprValue(v1, var)) // and not a variable
    //        {
    //            str << std::setw(numberPadding); // put in the padding
    //            num = boost::get<mbint>(v1);
    //        }
    //        else
    //        {
    //            num = boost::get<mbint>(var->value);
    //        }
    //        str << num;
    //        retStr = str.str();
    //    }
    //    return retStr;
    //}

    std::string StringifyExpression(const var_type& v1, mbint numberPadding)
    {
        mbint num;
        std::string retStr;
        if(GetExprValue(v1, num)) // if it's a number
        {
            std::ostringstream str;
            // put in the padding if it's been changed
            //
            // this seems to be the most compatible way 
            // of dealing with the inconsistencies in the
            // reference implementation
            if(numberPadding & Environment::PADDING_CHANGED_TAG)
            {
                str << std::setw(numberPadding &(~Environment::PADDING_CHANGED_TAG));
            }
            str << num;
            retStr = str.str();
        }
        else
        {
            GetExprValue(v1, retStr);
        }
        return retStr;
    }

    std::string StringifyExpression(const Vals& v1, mbint numberPadding)
    {
        return StringifyExpression(v1.var, numberPadding);
    }

    HRESULT CreateExecutionEnvironment(ExecutionParameters* pExParams, std::auto_ptr<Environment>& env)
    {
        HRESULT hr = S_OK;
        if(pExParams->pathToFile)
        {
            hr = Lexecutioner::CheckFileValidity(pExParams->pathToFile);
        }
        if(SUCCEEDED(hr))
        {
            try
            {
                env.reset(new Environment(pExParams));
            }
            catch(HRESULT hrFail)
            {
                hr = hrFail;
            }
        }
        return hr;
    }

    HMODULE GetDllModuleHandle()
    {
        HMODULE hMod = NULL;
        GetModuleHandleExW(
            GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
            reinterpret_cast<LPCWSTR>(&GetDllModuleHandle),
            &hMod);
        return hMod;
    }
}
